﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestLibrary;
using JSONDotNET;
using DynamicJSONDeserializer;

namespace JsonTests
{
    [TestGroup("Object Deserializing into DynamicJsonObject")]
    public class DeserializingIntoDynamicJsonObject
    {
        #region Helper objects
        enum E
        {
            A,
            B
        }
        class SimpleObj1
        {
            public int i { get; set; }
            public string s { get; set; }
            public bool b { get; set; }
            public double d { get; set; }
            public float f { get; set; }

            public E e { get; set; }
        }
        class SimpleObj2
        {
            public int i;
            public string s;
            public bool b;
            public double d;
            public float f;

            public E e;
        }
        class NullableObj
        {
            public int? i { get; set; }
            public bool? b { get; set; }
            public double? d { get; set; }
            public float? f { get; set; }

            public E? e { get; set; }
        }
        class GenericObj1<T, U>
        {
            public T i { get; set; }
            public U b;
        }
        class GenericObj2<T, U>
            where T : struct
            where U : struct
        {
            public T? i { get; set; }
            public U? b;
        }
        #endregion

        [TestCase("Basic deserializing")]
        public static void Test1()
        {
            var test = "{ \"i\" : 1, \"s\":\"aa\", \"b\":true, \"d\":1.3, \"f\":1.4, \"e\" : \"A\"}";
            var parse = JSONDotNET.Parser.ParseText(test);

            Helpers.Assert(parse != null, "We expected something to be parsed");
            //Helpers.Assert(parse.Unit.Members.Count == 0, "Expected 0 members!!!");


            var obj = DynamicJSONObject.Deserialize(parse);
            Helpers.Assert(obj != null, "Expected the object to be not null");

            Helpers.Assert(obj.i == 1, "Expected i = 1");
            Helpers.Assert(obj.s == "aa", "Expected s = aa");
            Helpers.Assert(obj.b == true, "Expected b = true");
            Helpers.Assert(obj.d == 1.3, "Expected d = 1.3");
            Helpers.Assert(obj.f == 1.4, "Expected f = 1.4");
            Helpers.Assert(obj.e == E.A.ToString(), "Expected e = A");
        }
    }

    [TestGroup("Array Deserializing into DynamicJsonObject")]
    public class ArrayDeserializingIntoDynamicJsonObject
    {
        #region Helper objects
        enum E
        {
            A,
            B
        }
        class SimpleObj1
        {
            public int[] i { get; set; }
            public string[] s { get; set; }
            public bool[] b { get; set; }
            public double[] d { get; set; }
            public float[] f { get; set; }

            public E[] e { get; set; }
        }
        class SimpleObj2
        {
            public int[] i;
            public string[] s;
            public bool[] b;
            public double[] d;
            public float[] f;

            public E[] e;
        }
        class SimpleObj3
        {
            public List<int> i { get; set; }
            public List<string> s { get; set; }
            public List<bool> b;
            public List<double> d;
            public List<float> f { get; set; }

            public List<E> e { get; set; }
        }

        class RefTypeObj
        {
            public NestedType[] ar;
        }
        class GenericRefTypeObj<T> where T : NestedType
        {
            public T[] ar;
            public T obj;
        }
        class NestedType
        {
            public int Prop { get; set; }
        }
        #endregion

        [TestCase("Basic array deserializing")]
        public static void Test1()
        {
            var test = "{ \"i\" : [1,2,3], \"s\": [\"aa\", \"bb\"], \"b\": [true, false], \"d\": [1.3, 1.4],  \"f\": [1.4,-0.4], \"e\" : [\"A\", 1] }";
            var parse = JSONDotNET.Parser.ParseText(test);

            Helpers.Assert(parse != null, "We expected something to be parsed");

            var obj = DynamicJSONObject.Deserialize(parse);
            Helpers.Assert(obj != null, "Expected the object to be not null");

            Helpers.Assert(obj.i.Length == 3, "Expected obj.i.Length = 3");
            Helpers.Assert(obj.i[0] == 1);
            Helpers.Assert(obj.i[1] == 2);
            Helpers.Assert(obj.i[2] == 3);

            Helpers.Assert(obj.s.Length == 2, "Expected obj.s.Length = 2");
            Helpers.Assert(obj.s[0] == "aa");
            Helpers.Assert(obj.s[1] == "bb");

            Helpers.Assert(obj.b.Length == 2, "Expected obj.b.Length = 2");
            Helpers.Assert(obj.b[0] == true);
            Helpers.Assert(obj.b[1] == false);

            Helpers.Assert(obj.d.Length == 2, "Expected obj.d.Length = 2");
            Helpers.Assert(obj.d[0] == 1.3);
            Helpers.Assert(obj.d[1] == 1.4);

            Helpers.Assert(obj.f.Length == 2, "Expected obj.f.Length = 2");
            Helpers.Assert(obj.f[0] == 1.4);
            Helpers.Assert(obj.f[1] == -0.4);

            Helpers.Assert(obj.e.Length == 2, "Expected obj.e.Length = 2");
            Helpers.Assert(obj.e[0] == "A");
            Helpers.Assert(obj.e[1] == 1);
        }

        [TestCase("Basic ref-type array deserializing")]
        public static void Test2()
        {
            var test = "{ \"ar\" : [ { \"Prop\":1 }, { \"Prop\":2 } ] }";
            var parse = JSONDotNET.Parser.ParseText(test);

            Helpers.Assert(parse != null, "We expected something to be parsed");

            var obj = DynamicJSONObject.Deserialize(parse);
            Helpers.Assert(obj != null, "Expected the object to be not null");

            Helpers.Assert(obj.ar.Length == 2, "Expected ar.Length = 2");
            Helpers.Assert(obj.ar[0].Prop == 1);
            Helpers.Assert(obj.ar[1].Prop == 2);
        }

        [TestCase("Ref-type array deserializing")]
        public static void Test3()
        {
            var test = @"{ 
                ""ar"" :  [  
                            { ""Prop"":1 }, 
                            { ""Prop"":2 } 
                           ] ,
                ""obj"" :  { 
                            ""Prop"":3 
                           }
                          }";
            var parse = JSONDotNET.Parser.ParseText(test);

            Helpers.Assert(parse != null, "We expected something to be parsed");

            var obj = DynamicJSONObject.Deserialize(parse);
            Helpers.Assert(obj != null, "Expected the object to be not null");

            Helpers.Assert(obj.ar.Length == 2, "Expected ar.Length = 2");
            Helpers.Assert(obj.ar[0].Prop == 1);
            Helpers.Assert(obj.ar[1].Prop == 2);
            Helpers.Assert(obj.obj.Prop == 3);
        }
    }

    [TestGroup("SmugMug real world objects using dynamic JSON")]
    public class SmugMugResponses
    {
        [TestCase("SmugMug.Albums.get")]
        public static void ParseAlbumsGet()
        {
            var test = @"{
  ""stat"": ""ok"",
  ""method"": ""smugmug.albums.get"",
  ""Albums"": [
    {
      ""id"": 1234,
      ""Key"": ""xCXXu"",
      ""Category"": {
        ""id"": 0,
        ""Name"": ""Other""
      },
      ""Title"": ""My Birthday 2008""
    }
  ]
}";
            var obj = DynamicJSONDeserializer.DynamicJSONObject.Deserialize(test);
        }

        [TestCase("SmugMug.User.GetTree")]
        public static void ParseUserGetTree()
        {
            var test = @"{
  ""stat"": ""ok"",
  ""method"": ""smugmug.users.getTree"",
  ""Categories"": [
    {
      ""id"": 0,
      ""Name"": ""Other"",
      ""SubCategories"": [
        {
          ""id"": 1000,
          ""Name"": ""Testing""
        }
      ],
      ""Albums"": [
        {
          ""id"": 1234,
          ""Key"": ""xCXXu"",
          ""Title"": ""My Birthday 2008""
        }
      ]
    },
    {
      ""id"": 1,
      ""Name"": ""Animals""
    },
    {
      ""id"": 2,
      ""Name"": ""Architecture""
    },
    {
      ""id"": 3,
      ""Name"": ""Art""
    },
    {
      ""id"": 4,
      ""Name"": ""Boats""
    },
    {
      ""id"": 13,
      ""Name"": ""Landscapes"",
      ""SubCategories"": [
        {
          ""id"": 1234,
          ""Name"": ""Sunrise""
        },
        {
          ""id"": 2345,
          ""Name"": ""Sunset""
        }
      ]
    }
  ]
}";
            var obj = DynamicJSONDeserializer.DynamicJSONObject.Deserialize(test);
        }
    }
}
